﻿using System.Collections.Generic;
using System.IO;
using System.Net.Sockets;
using System.Text.RegularExpressions;

namespace FemtoHttpd
{
    public class FemtoHttpRequest
    {
        private readonly Stream input;

        public readonly Dictionary<string, string> Header = new Dictionary<string, string>();

        public string Method { get; private set; }

        public string Url { get; private set; }

        //public string Body { get; set; }

        public string Protocol { get; private set; }

        public Dictionary<string, string> QueryParameters { get; private set; } = new Dictionary<string, string>();

        private FemtoHttpRequest(Stream input)
        {
            this.input = input;
        }
        /// <summary>
        /// Parse request header and return the request
        /// </summary>
        /// <param name="input"></param>
        /// <returns>return null,if this is bad request</returns>
        public static FemtoHttpRequest Get(Stream input)
        {
            var r = new FemtoHttpRequest(input);
            return r.TryParse() ? r : null;
        }
        public bool TryParse()
        {
            try
            {
                HeaderReader reader = new HeaderReader(input);
                if (!reader.ReadAllLine(out string[] linesRaw))
                {
                    return false;
                }
                string[] request = linesRaw[0].Split(' ');

                Method = request[0].ToUpperInvariant();

                string completeQuery = request[1];
                string[] queryString = completeQuery.Split('?');

                Url = queryString[0];
                if (queryString.Length > 1)
                {
                    QueryParameters = ParseQueryString(queryString[1]);
                }

                Protocol = request[2];

                for (int i = 1; i < linesRaw.Length; ++i)
                {
                    string line = linesRaw[i];
                    // header
                    int separater = line.IndexOf(":");
                    string key = line.Substring(0, separater);
                    string value = line.Substring(separater + 2);
                    Header[key] = value;
                }
                return true;
            }
            catch
            {
                // error while parsing
                return false;
            }
        }
        /// <summary>
        /// Get request content,like body
        /// </summary>
        /// <returns></returns>
        public Stream GetContent()
        {
            return input;
        }
        public static Dictionary<string, string> ParseQueryString(string queryString)
        {
            Dictionary<string, string> queryParameters = new Dictionary<string, string>();

            var matches = Regex.Matches(queryString, @"&?([^\=]+)=([^&]+)");
            foreach (Match match in matches)
            {
                string key = match.Groups[1].Value;
                string value = match.Groups[2].Value;
                queryParameters[key] = value;
            }
            return queryParameters;
        }
    }
}
